﻿// MakingWaves: GoogleMaps

/*global google document */

var openWaves;
if (!openWaves) {
    openWaves = {};
} else if (typeof openWaves !== "object") {
    throw new Error("openWaves already exists and is not an object");
}

openWaves.GoogleMapControl = function (settings) {
    var self = this;

    this.mapContainerId = settings.mapContainerId;
    this.dataItems = settings.dataItems;
    this.viewport = settings.viewport;
    this.markerIconUrl = settings.markerIconUrl;

    this.markers = [];
    
    this.mapOptions = {
        zoom: 0,
        center: new google.maps.LatLng(0, 0),
        mapTypeId: google.maps.MapTypeId.ROADMAP
    };

    this.onMarkerClicked = function (map, marker) {
        if (marker.infoWindow) {
            marker.infoWindow.open(map);
        }
    };

    this.onMarkerCreated = function (marker) {
        marker.setMap(self.map);
    };

    function addMarkerClickListener(marker) {
        google.maps.event.addListener(marker, 'click', function () {
            self.onMarkerClicked(self.map, marker);
        });
    }

    function addMarkers() {
        var i, markerLatLng, marker, infoWindow;
        if (!self.dataItems) {
            throw new Error("dataItems argument is not valid");
        }
        for (i = 0; i < self.dataItems.length; i += 1) {
            markerLatLng = new google.maps.LatLng(self.dataItems[i].location.Latitude, self.dataItems[i].location.Longitude);
            marker = new google.maps.Marker({
                position: markerLatLng,
                title: self.dataItems[i].toolTip,
                icon: self.markerIconUrl
            });

            marker.dataItem = self.dataItems[i];
            
            if (self.dataItems[i].infoWindowContent) {
                infoWindow = new google.maps.InfoWindow({ content: self.dataItems[i].infoWindowContent, position: markerLatLng });
                marker.infoWindow = infoWindow;
            }
            
            self.markers.push(marker);
            self.onMarkerCreated(marker);

            addMarkerClickListener(marker);
        }
    }

    this.fitBounds = function (bounds) {
        var topLeftBound = new google.maps.LatLng(bounds.TopLeft.Latitude, bounds.TopLeft.Longitude),
            bottomRightBound = new google.maps.LatLng(bounds.BottomRight.Latitude, bounds.BottomRight.Longitude),
            latLngbounds = new google.maps.LatLngBounds(topLeftBound, bottomRightBound);
        self.map.fitBounds(latLngbounds);
    };

    this.centerAndZoom = function (center, zoom) {
        self.map.setCenter(new google.maps.LatLng(center.Latitude, center.Longitude));
        self.map.setZoom(zoom);
    };

    this.applyViewportSettings = function () {
        if (!self.viewport) {
            return;
        }
        if (self.viewport.Bounds) {
            self.fitBounds(self.viewport.Bounds);
        } else if (self.viewport.Center) {
            self.centerAndZoom(self.viewport.Center, self.viewport.Zoom);
        }
    };

    this.initialize = function () {
        self.map = new google.maps.Map(document.getElementById(self.mapContainerId), self.mapOptions);
        self.applyViewportSettings();
        addMarkers();
    };

    this.filterMarkers = function (predicate) {
        var i, marker;
        for (i = 0; i < self.markers.length; i += 1) {
            marker = self.markers[i];
            marker.setVisible(predicate(marker));
        }
    };
};